﻿using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Input;
using InseSoft.Infraestructure;
using InseSoft.Models;
using InseSoft.Models.Entities;

namespace InseSoft.ViewModels
{
    public class LoginViewModel : ObservableObject
    {
        #region Declarations

        private IEnumerable<Empresa> empresas;
        private string user;
        private bool isNotLoggedIn = true;
        private bool invalidPassword;
        private readonly ApplicationSession session;

        #endregion

        #region Constructor

        public LoginViewModel(IInseContext dbContext, ApplicationSession session)
        {
            this.session = session;
            DbContext = dbContext;
            ResetValues();
        }

        #endregion

        #region Properties

        public IInseContext DbContext { get; set; }
        
        public string User
        {
            get { return user; }
            set
            {
                user = value;
                OnPropertyChanged(() => User);
            }
        }

        public string Password { get; set; }

        public IEnumerable<Empresa> Empresas
        {
            get { return empresas; }
            set
            {
                empresas = value;
                OnPropertyChanged(() => Empresas);
            }
        }

        public Empresa SelectedEmpresa { get; set; }

        public bool InvalidPassword
        {
            get { return invalidPassword; }
            set
            {
                invalidPassword = value;
                OnPropertyChanged(() => InvalidPassword);
            }
        }

        public bool IsNotLoggedIn
        {
            get { return isNotLoggedIn; }
            set
            {
                isNotLoggedIn = value;
                ResetValues();
                OnPropertyChanged(() => IsNotLoggedIn);
            }
        }

        public void ResetValues()
        {
            Empresas = DbContext.Empresas.AsNoTracking().ToArray();
            SelectedEmpresa = Empresas.FirstOrDefault();
            session.Clear();
            User = "";
            InvalidPassword = false;
        }

        #endregion

        #region Commands

        public ICommand AcceptCommand
        {
            get { return new RelayCommandWithParameter(AcceptExecute); }
        }
        
        #endregion

        #region Methods

        private void AcceptExecute(object parameter)
        {
            InvalidPassword = true;
            var passwordBox = parameter as PasswordBox;
            if (passwordBox != null)
            {
                ValidateUser(User, passwordBox.Password);
                passwordBox.Clear();
            }
        }

        private void ValidateUser(string userName, string password)
        {
            var userEntity = (from u in DbContext.Usuarios
                              where u.Empresa.Id == SelectedEmpresa.Id
                                   && u.NombreUsuario == userName
                                   && u.Clave == password
                              select u)
                              .Include(p => p.Permisos)
                              .AsNoTracking()
                              .FirstOrDefault();
            if (userEntity != null)
            {
                InvalidPassword = false;
                IsNotLoggedIn = false;
                session.Empresa = SelectedEmpresa;
                session.Usuario = userEntity;
            }
        }
        
        #endregion
    }
}
